<template>
  <div class="channel-edit">
    <van-nav-bar class="page-nav-bar" title="频道编辑" />
    <div>
      <!-- 我的频道 -->
      <div>
        <!-- 我的频道头部 -->
        <div class="my-box">
          <div class="fz40">我的频道({{ myChannels.length }})</div>
          <van-button
            size="mini"
            type="danger"
            plain
            round
            @click="onClickEditOrFinish"
            >&nbsp;&nbsp;{{
              isEditStatus ? "完成" : "编辑"
            }}&nbsp;&nbsp;</van-button
          >
        </div>
        <!-- /我的频道头部 -->
        <!-- 我的频道列表 -->
        <div class="list">
          <div
            v-for="(v, i) of myChannels"
            :key="v.id"
            class="list-item"
            :class="{ active: isEditStatus && v.id !== 0, red: v.id === activeChannel.id }"
            @click="onClickMyChannel(v, i)"
          >
            {{ v.name }}
          </div>
        </div>
        <!-- /我的频道列表 -->
      </div>
      <!-- /我的频道 -->
      <!-- 推荐频道 -->
      <div>
        <div>
          <!-- 推荐频道头部 -->
          <div class="fz40 tj-box">推荐频道({{ tjChannels.length }})</div>
          <!-- /推荐频道头部 -->
          <!-- 推荐频道列表 -->
          <div class="list">
            <div
              v-for="v of tjChannels"
              :key="v.id"
              class="list-item"
              :class="{ red: v.id === activeChannel.id }"
              @click="onClickTjChannel(v)"
            >
              {{ v.name }}
            </div>
          </div>
          <!-- /推荐频道列表 -->
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as storage from '../../../../utils/storage'
// import * as storage from '@/utils/storage'
import _ from 'lodash'
export default {
  name: 'ChannelEdit',
  props: {
    activeChannel: {
      type: Object,
      required: true
    }
    // channels: {
    //   type: Array,
    //   required: true
    // }
  },
  data () {
    return {
      channels: [], // 所有频道
      myChannelsBak: [], // 备份的我的频道
      myChannels: [],
      isEditStatus: false // 是否为编辑状态
    }
  },
  computed: {
    tjChannels () {
      // 拿出 所有频道中 不在 我的频道列表中的 频道
      return this.channels.filter((v) => !this.myChannels.some((v2) => v2.id === v.id))
    },
    // 是否改变了
    isChanged () {
      // 如何判断两个数组是否相等？
      // _.differenceBy 是以第一个数组为基准的，比如 [1, 2, 3] 和 [1, 2, 3, 4]，结果是 []
      // 基于这个  _.differenceBy 的比较逻辑，我们知道，如果两个数组的长度是一样的，那么 这个方法是没问题的
      // 所以，换句话说，如果两个数组的长度都不一样，那肯定不相等，代表有变化
      if (this.myChannels.length !== this.myChannelsBak.length) return true
      return _.differenceBy(this.myChannels, this.myChannelsBak, 'id').length !== 0
    }
  },
  methods: {
    resetMyChannles () {
      if (this.isEditStatus) {
        this.myChannels = this.myChannelsBak
        this.isEditStatus = false
      }
    },
    onClickEditOrFinish () {
      if (this.isEditStatus) { // 是编辑，那就是点的完成
        // if ... else 嵌套层级多一点没关系，因为这样风格的代码，逻辑严谨，不容易出 bug
        if (this.isChanged) {
          if (this.$store.state.userToken) {
            const newMyChannels = this.myChannels.map(({ id }, seq) => ({ id, seq }))
            this.apis.channel.resetUserChannels(newMyChannels).then(() => {
            // Promise.reject(new Error('模拟错误')).then(() => {
              this.$toast.success('编辑成功')
              this.isEditStatus = false
              this.$emit('updateMyChannels', this.myChannels)
            }, () => {
              this.$toast.fail('编辑失败，请稍后重试！')
              this.resetMyChannles()
            })
          } else {
            storage.setItem(storage.KEY_MY_CHANNELS, this.myChannels)
            this.$emit('updateMyChannels', this.myChannels)
            this.isEditStatus = false
          }
        } else {
          this.$emit('updateMyChannels', this.myChannels)
          storage.setItem(storage.KEY_MY_CHANNELS, this.myChannels)
          this.isEditStatus = false
        }
      } else { // 如果不是编辑，那么就是点的编辑
        // 将 我的频道列表 浅拷贝 备份，注意：一定不能直接赋值，会指向同一个地址，从而互相影响
        this.myChannelsBak = this.myChannels
        this.isEditStatus = !this.isEditStatus
      }
      // 这个代码比上面的 .then 回调先执行，因为是同步代码，所以 resetMyChannles 函数内部的 if 就进不去了
      // this.isEditStatus = !this.isEditStatus
    },
    // 当点击我的频道时
    onClickMyChannel (myChannel, index) {
      // 先看当前是否为编辑状态
      if (this.isEditStatus) {
        // 如果是，则从我的频道中删除，推荐频道会自动重新计算
        if (myChannel.id === 0) return // 如果点的是推荐，那么直接终止后续的代码执行
        this.myChannels.splice(index, 1)
      } else {
        // 如果不是，则跳转到该频道，关闭弹层
        // （这个需求，就得子传父通讯了）
        this.$emit('switchChannel', myChannel)
      }
    },
    // 当点击推荐频道时
    onClickTjChannel (tjChannel) {
      // 要将点击的这个推荐频道加入到我的频道中
      // 你咋知道点的是哪个推荐频道嘞？
      // if (this.isEditStatus) { // 如果是，加加入到我的频道中
      //   this.myChannels.push(tjChannel)
      // } else { // 如果不是，就切换频道
      //   this.$emit('switchChannel', tjChannel)
      // }
      if (this.isEditStatus) { // 如果是，加加入到我的频道中
        this.myChannels.push(tjChannel)
      } else {
        this.$toast('请先点击编辑')
      }
    }
  },
  created () {
    // 这是拿所有频道
    this.apis.channel.getChannels().then((res) => {
      this.channels = res.data.data.channels
    })

    if (this.$store.state.userToken) { // 登录了，发请求
      this.apis.channel.getUserChannels().then(myChannels => {
        this.myChannels = myChannels
      })
    } else { // 没登录，拿本地
      this.myChannels = storage.getItem(storage.KEY_MY_CHANNELS) || this.channels.filter(v => v.id === 0)
    }
  }
}
</script>

<style lang="less" scoped>
.channel-edit {
  .list {
    display: flex;
    flex-wrap: wrap;
    padding: 0 10px;
    .list-item {
      cursor: pointer;
      flex: 25%;
      height: 100px;
      line-height: 90px;
      text-align: center;
      border-radius: 20px;
      box-sizing: border-box;
      border: 10px solid #fff;
      flex-grow: 0; // 当有多余的剩余空间时，是否允许放大
      background-color: #f3f5f7;
      color: #000;
      font-size: 30px;
      &.active {
        position: relative;
        &::before {
          content: "x";
          font-size: 30px;
          line-height: 30px;
          border-radius: 50%;
          display: block;
          width: 30px;
          color: #fff;
          height: 30px;
          background-color: red;
          position: absolute;
          right: -10px;
          top: -10px;
          z-index: 1;
        }
      }
      &.red {
        color: red;
      }
    }
  }
  .tj-box {
    padding: 20px;
  }
  .my-box {
    display: flex;
    justify-content: space-between;
    padding: 20px;
  }
  .page-nav-bar {
    background-color: #fff;
    /deep/ .van-nav-bar__title {
      color: #000;
    }
  }
  .fz40 {
    font-size: 40px;
  }
}
</style>
